package com.yixun.qfbao.hander;

import com.alibaba.fastjson.JSONObject;
import com.yixun.qfbao.common.excel.FastExcel;
import com.yixun.qfbao.common.model.CustomerPremisesModel;
import com.yixun.qfbao.dto.base.BaseResponseDTO;
import com.yixun.qfbao.model.Department;
import com.yixun.qfbao.model.PartnerInfo;
import com.yixun.qfbao.model.dto.DepartmentDto;
import com.yixun.qfbao.model.dto.ImportLogDto;
import com.yixun.qfbao.model.dto.PartnerInfoDto;
import com.yixun.qfbao.model.enums.DelFlagEnum;
import com.yixun.qfbao.model.enums.ImpBusinessTypeEnum;
import com.yixun.qfbao.model.enums.MechanismAccountTypeEnum;
import com.yixun.qfbao.dao.DepartmentDao;
import com.yixun.qfbao.service.ImportLogService;
import com.yixun.qfbao.service.PartnerInfoService;
import com.yixun.qfbao.util.PasswordUtil;
import com.yixun.qfbao.util.exception.TServerException;
import com.yixun.qfbao.utils.LoginUtils;
import com.yixun.qfbao.xf.model.enums.PartnerStatusEnum;
import com.yixun.qfbao.xf.model.enums.ResultEnum;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.util.*;

/**
 * 批量导入报备
 * @author jhsong
 *
 */
@Service("importCusPreHander")
public class ImportCusPreHander {

	private static final Logger logger = LoggerFactory.getLogger(ImportCusPreHander.class);
	
	@Autowired
	private ImportLogService importLogService;
	@Autowired
	private LoginUtils loginUtils;
	@Autowired
	private PartnerInfoService partnerInfoService;
	@Autowired
	private DepartmentDao departmentDao;
	
	public BaseResponseDTO doBusiness(MultipartHttpServletRequest request, String userId) {
		BaseResponseDTO res = new BaseResponseDTO();
		PartnerInfo pi = loginUtils.getUser(userId);
		try {
			//导入的批次
			String batchId= UUID.randomUUID().toString();
			long startTime = System.currentTimeMillis();
			logger.info("upload file start, batchId = " + batchId + ",start time = " + startTime);
			Iterator<String> fileNames = request.getFileNames();
			if (fileNames.hasNext()) {
				//文件参数名
				String fileName = fileNames.next();
				//获取到文件
				MultipartFile file = request.getFile(fileName);
				//文件后缀名
				String suffix = request.getParameter("suffix");
				if (null == file) {
					res.setResult(ResultEnum.FAIL.getNo());
					res.setErrorMsg("请上传有效非空Excel文件。");
					return res;
				}
				FastExcel fastExcel=new FastExcel(file.getInputStream());
				fastExcel.setStartRow(3);
				List<CustomerPremisesModel> customerList = fastExcel.parse(CustomerPremisesModel.class);
				fastExcel.close();

				if(null == customerList || customerList.size() == 0){
					res.setErrorCode(ResultEnum.FAIL.getNo());
					res.setErrorMsg("单次批量报备,最少需导入 1笔。");
					return res;
				}

				if(null != customerList && customerList.size() > 500){
					res.setResult(ResultEnum.FAIL.getNo());
					res.setErrorMsg("单次批量报备,最多导入 500 笔。");
					return res;
				}
				List<PartnerInfo> partnerInfoList = partnerInfoService.getRegisterPartnerByAgentCompany(null, pi.getHigherid());
				Map<String, PartnerInfo> partnerInfoMap = new HashMap<>();
				if(null != partnerInfoList && partnerInfoList.size() > 0){
					for(PartnerInfo partnerInfo: partnerInfoList){
						partnerInfoMap.put(partnerInfo.getPhone(), partnerInfo);
					}
				}
				//经纪人所属公司的顶级部门
				//用于: 当导入经纪人不存在时,添加经纪人挂到此部门下
				DepartmentDto deptDto = new DepartmentDto();
				deptDto.setMerchantId(pi.getHigherid());
				deptDto.setParentId(0L);
				Department dept = departmentDao.selectByDto(deptDto);
				long deptId = dept.getId();
				List<CustomerPremisesModel> addCustomerList = new ArrayList<>();
				for(CustomerPremisesModel model: customerList){
					if(StringUtils.isBlank(model.getAgentName())
						|| StringUtils.isBlank(model.getAgentPhone())){
						continue;
					}
					PartnerInfo partnerInfo = partnerInfoMap.get(model.getAgentPhone());
					if(null != partnerInfo){
						//1、存在用户,直接分配至当前记录
						model.setStaffId(partnerInfo.getId());
						model.setStaffCompany(partnerInfo.getHigherid());
					}else{
						//2、不存在用户,新增后再分配给当前记录
						PartnerInfoDto piDto = new PartnerInfoDto();
						piDto.setPhone(model.getAgentPhone());
						piDto.setAccountName(model.getAgentName());
						piDto.setAccountType(MechanismAccountTypeEnum.individual.getNo());
						piDto.setStatus(PartnerStatusEnum.VALID.getNo());
						piDto.setPassword(PasswordUtil.md5Hex("12345678"));
						piDto.setHigherid(pi.getHigherid());
						piDto.setDeptId(deptId);
						piDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
						piDto = partnerInfoService.create(piDto);
						partnerInfoMap.put(model.getAgentPhone(), piDto);

						model.setStaffId(piDto.getId());
						model.setStaffCompany(pi.getHigherid());
					}
					addCustomerList.add(model);
				}
				if(CollectionUtils.isEmpty(addCustomerList)){
					res.setResult(ResultEnum.FAIL.getNo());
					res.setErrorMsg("数据异常，请检查后重新导入");
					return res;
				}
				ImportLogDto importLogDto = new ImportLogDto();
				importLogDto.setBatchId(batchId);
				importLogDto.setBusinesstype(ImpBusinessTypeEnum.CUSPRE.getNo());
				importLogDto.setOriginalData(JSONObject.toJSONString(addCustomerList));
				importLogDto.setMerchantId(null == pi ? null: pi.getHigherid());
				importLogDto.setDelFlag(DelFlagEnum.UNDEL.getNo());
				importLogDto.setCreateUserId(null == pi ? null: pi.getId());
				importLogService.create(importLogDto);
			}else{
				res.setResult(ResultEnum.FAIL.getNo());
				res.setErrorMsg("请上传有效非空Excel文件。");
				return res;
			}

			long endTime = System.currentTimeMillis();
			logger.info("upload file end, batchId = " + batchId + ",end time = " + startTime);
			logger.info("upload file batchId = " + batchId + ", use time = " + (endTime - startTime));
			res.setResData(batchId);
			res.setResult(ResultEnum.SUCCESS.getNo());
		}catch(TServerException e){
			logger.error("tserver exception error: {}", e);
			res.setResult(ResultEnum.FAIL.getNo());
			res.setErrorMsg(e.getErrorMsg());
		} catch (Exception e) {
			logger.error("上传文件失败: {}", e);
			res.setResult(ResultEnum.FAIL.getNo());
			res.setErrorMsg("文件导入失败");
		}
		return res;
	}
	
}
